package com.cykj.controller;

import com.cykj.common.dto.ResponseDTO;
import com.cykj.service.InterviewSessionService;
import com.cykj.service.MockService;
import com.cykj.vo.InterviewDataDO;
import com.cykj.vo.MockVO;
import dev.langchain4j.model.openai.OpenAiChatModel;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/interview")
@Tag(name = "AI面试功能")
public class AIInterviewController {
    private static final int MAX_QUESTIONS = 5;

    @Autowired
    private OpenAiChatModel openAiChatModel;
    @Autowired
    private InterviewSessionService sessionService;
    @Autowired
    private MockService mockService;

    // ============ 公开接口 ============

    @PostMapping("/start")
    public ResponseEntity<ResponseDTO> startInterview(
            @RequestBody MockVO mockVO,
            HttpServletRequest request) {

        String sessionId = request.getSession().getId();
        String[] questions = generateInitialQuestions(mockVO.getJob());

        InterviewSessionService.InterviewSession session =
                sessionService.createOrGetSession(sessionId, mockVO.getJob(), List.of(questions));

        // 保存提问到数据库
        Integer mockId = mockService.insertMock(sessionId, mockVO.getUserId(), session.getQuestions().get(0));

        InterviewDataDO data = InterviewDataDO.buildBasicResponse(
                sessionId, mockVO.getJob(), session.getQuestions().get(0),
                1, MAX_QUESTIONS, false
        );
        data.setMockId(mockId);

        return ResponseEntity.ok(ResponseDTO.success(data));
    }

    @PostMapping("/submit-answer")
    public ResponseEntity<ResponseDTO> submitAnswer(
            @RequestBody MockVO mockVO) {

        // 检查会话状态
        ResponseEntity<ResponseDTO> statusCheck = checkSessionStatus(mockVO.getSessionId());
        if (statusCheck.getStatusCode() != HttpStatus.OK) {
            return statusCheck;
        }

        InterviewSessionService.InterviewSession session =
                sessionService.getAndUpdateSession(mockVO.getSessionId());

        // 保存答案
        session.getUserAnswers().add(mockVO.getAnswer());
        session.getAskedQuestions().add(getCurrentQuestion(session));

        // 获取评价
        String feedback = generateFeedback(session, mockVO.getAnswer());

        // 保存用户回答到数据库（答案和评价用|分隔）
        String answerWithFeedback = mockVO.getAnswer() + "|" + feedback;
        mockService.insertUserChat(mockVO.getSessionId(), mockVO.getUserId(), answerWithFeedback, mockVO.getMockId());

        InterviewDataDO data = new InterviewDataDO();
        data.setFeedback(feedback);

        // 检查是否结束
        if (shouldCompleteInterview(session)) {
            return completeInterview(session, data,mockVO.getMockId());
        }

        // 返回下一题
        String nextQuestion = getNextQuestion(session);
        session.getAskedQuestions().add(nextQuestion);
        session.setCurrentQuestionIndex(session.getCurrentQuestionIndex() + 1);

        // 将AI的新问题存入数据库
        mockService.insertAiChat(mockVO.getSessionId(), mockVO.getUserId(), nextQuestion, mockVO.getMockId());

        // 构建返回数据
        data = InterviewDataDO.buildBasicResponse(
                mockVO.getSessionId(), session.getJob(), nextQuestion,
                session.getCurrentQuestionIndex() + 1, MAX_QUESTIONS, false
        );
        data.setMockId(mockVO.getMockId());
        data.setFeedback(feedback);

        return ResponseEntity.ok(ResponseDTO.success(data));
    }

    @GetMapping("/status")
    public ResponseEntity<ResponseDTO> getStatus(
            @RequestBody MockVO mockVO) {

        ResponseEntity<ResponseDTO> statusCheck = checkSessionStatus(mockVO.getSessionId());
        if (statusCheck.getStatusCode() != HttpStatus.OK) {
            return statusCheck;
        }

        InterviewSessionService.InterviewSession session =
                sessionService.getAndUpdateSession(mockVO.getSessionId());

        InterviewDataDO data = new InterviewDataDO();
        data.setSessionId(mockVO.getSessionId());
        data.setJob(session.getJob());
        data.setQuestionIndex(session.getCurrentQuestionIndex());
        data.setTotalQuestions(MAX_QUESTIONS);
        data.setIsCompleted(session.isCompleted());
        data.setAskedCount(session.getAskedQuestions().size());
        data.setAnsweredCount(session.getUserAnswers().size());

        return ResponseEntity.ok(ResponseDTO.success(data));
    }

    @PostMapping("/heartbeat")
    public ResponseEntity<ResponseDTO> heartbeat(@RequestBody MockVO mockVO) {
        InterviewSessionService.InterviewSession session =
                sessionService.getAndUpdateSession(mockVO.getSessionId());

        if (session == null || session.isCompleted()) {
            return ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT)
                    .body(ResponseDTO.error(408, "会话已超时或结束"));
        }
        return ResponseEntity.ok(ResponseDTO.success("active"));
    }

    @PostMapping("/end")
    public ResponseEntity<ResponseDTO> endInterview(
            @RequestBody MockVO mockVO) {

        InterviewSessionService.InterviewSession session =
                sessionService.getSession(mockVO.getSessionId());

        if (session == null) {
            return ResponseEntity.badRequest()
                    .body(ResponseDTO.error(400, "会话不存在"));
        }

        InterviewDataDO data = new InterviewDataDO();
        data.setOverallFeedback("会话结束");
        data.setIsCompleted(true);
        data.setAskedCount(session.getAskedQuestions().size());
        data.setAnsweredCount(session.getUserAnswers().size());

        session.setCompleted(true);
        sessionService.clearSession(mockVO.getSessionId());

        return ResponseEntity.ok(ResponseDTO.success(data));
    }

    // ============ 私有方法 ============

    private ResponseEntity<ResponseDTO> checkSessionStatus(String sessionId) {
        InterviewSessionService.InterviewSession session =
                sessionService.getAndUpdateSession(sessionId);

        if (session == null) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(ResponseDTO.error(404, "会话不存在"));
        }

        if (session.isCompleted()) {
            return ResponseEntity.status(HttpStatus.GONE)
                    .body(ResponseDTO.error(410, "会话已结束"));
        }

        return ResponseEntity.ok(ResponseDTO.success("会话有效"));
    }

    private String[] generateInitialQuestions(String job) {
        String prompt = String.format(
                "请为%s岗位生成3个核心面试问题，用'|'分隔。只要问题不要说明", job);
        return openAiChatModel.chat(prompt).split("\\|");
    }

    private String generateFeedback(
            InterviewSessionService.InterviewSession session,
            String answer) {

        String currentQuestion = getCurrentQuestion(session);
        String prompt = String.format(
                "作为%s面试官评价极简以下回答：\n问：%s\n答：%s\n\n" +
                        "指出3个优点和2个不足，用'优点：'和'不足：'开头，限100字",
                session.getJob(), currentQuestion, answer);

        return openAiChatModel.chat(prompt);
    }

    private String generateOverallFeedback(
            InterviewSessionService.InterviewSession session) {

        StringBuilder prompt = new StringBuilder();
        prompt.append("作为").append(session.getJob())
                .append("面试官，根据以下问答给出综合评价：\n\n");

        for (int i = 0; i < session.getAskedQuestions().size(); i++) {
            prompt.append(String.format("%d. 问：%s\n答：%s\n\n",
                    i + 1,
                    session.getAskedQuestions().get(i),
                    i < session.getUserAnswers().size() ?
                            session.getUserAnswers().get(i) : "无回答"));
        }

        prompt.append("从技术能力、问题解决、沟通表达三方面评价，限150字");
        return openAiChatModel.chat(prompt.toString());
    }

    private boolean shouldCompleteInterview(
            InterviewSessionService.InterviewSession session) {

        return session.getAskedQuestions().size() >= MAX_QUESTIONS;
    }

    private String getCurrentQuestion(
            InterviewSessionService.InterviewSession session) {

        return session.getQuestions().get(session.getCurrentQuestionIndex());
    }

    private String getNextQuestion(
            InterviewSessionService.InterviewSession session) {

        if (session.getCurrentQuestionIndex() + 1 < session.getQuestions().size()) {
            return session.getQuestions().get(session.getCurrentQuestionIndex() + 1);
        }

        String lastQ = session.getAskedQuestions().get(session.getAskedQuestions().size() - 1);
        String lastA = session.getUserAnswers().get(session.getUserAnswers().size() - 1);

        String prompt = String.format(
                "基于以下问答生成追问问题：\n问：极简%s\n答：极简%s\n\n只要问题不要说明", lastQ, lastA);

        return openAiChatModel.chat(prompt);
    }

    private ResponseEntity<ResponseDTO> completeInterview(
            InterviewSessionService.InterviewSession session,
            InterviewDataDO data,
            Integer mockId) {

        String overallFeedback = generateOverallFeedback(session);
        mockService.updateMock(overallFeedback,mockId);
        data.setIsCompleted(true);
        data.setOverallFeedback(overallFeedback);
        data.setAskedCount(session.getAskedQuestions().size());
        data.setAnsweredCount(session.getUserAnswers().size());

        session.setCompleted(true);
        sessionService.clearSession(session.getSessionId());

        return ResponseEntity.ok(ResponseDTO.success(data));
    }
}